home *** CD-ROM | disk | FTP | other *** search
/ Super PC 34 / Super PC 34 (Shareware).iso / spc / UTIL / FASTCD09 / FASTCD.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-02-07  |  29.0 KB  |  1,022 lines

  1. ;─────────────────────────────────────
  2. ;·▄▄▄  ▄▄▄·  .▄▄ ·  ▄▄▄▄▄  ▄▄·  ·▄▄▄▄
  3. ;▐▄▄· ▐█ ▀█  ▐█ ▀.  ∙██   ▐█ ▌■ ██■ ██
  4. ;██■  ▄█▀▀█  ▄▀▀▀█▄  ▐█.■ ██ ▄▄ ▐█· ▐█
  5. ;██▌. ▐█ ■▐▌ ▐█▄■▐█  ▐█▌· ▐███▌ ██. ██
  6. ;▀▀▀   ▀  ▀   ▀▀▀▀   ▀▀▀  ·▀▀▀  ▀▀▀▀▀∙
  7. ;───────────────────────────────v0.9ß─
  8. ; A Tiny TSR CD Digital Audio Player
  9. ;├───────────────────────────────────┤
  10. ;∙ ■ Play·Stop·Skip·Volume functions ∙
  11. ;│ ■ Consumes 2000 bytes of memory   │
  12. ;∙ ■ Full .ASM sources included      ∙
  13. ;╘═══════════════════════════════════╛
  14.  
  15. ;          Author: Johan Prins
  16. ;Internet address: jprins@dmrt.nl
  17.  
  18. CodeSg        segment
  19.         assume cs:codesg,ds:codesg
  20.  
  21. BeginDump    EQU    $        ;Roy Silvernail - Keep TASM 1.0 happy
  22.                     ;when computing # resident paragraphs.
  23. ;
  24.         org    2CH        ;v0.01 ORG in PSP to pick up the
  25. envseg        label    word        ;v0.01 Environment Segment.
  26. ;
  27.         org    100h        ;ORG for all COM programs.
  28. ;
  29. Entry        PROC    NEAR        ;v0.01
  30.         jmp    TSRinit        ;Jump over resident portion and
  31.                     ;initialize things and make code
  32.                     ;between Entry: and TSRinit: resident.
  33. ;
  34. oldint09        dd      ?               ;Keyboard Hardware Interrupt.
  35. oldint13        dd      ?               ;Disk BIOS Interrupt.
  36. oldint16        dd      ?               ;Keyboard BIOS Interrupt.
  37. oldint28        dd      ?               ;DOS Idle Interrupt.
  38. ;
  39. HOOK09        equ    09h            ;Hooked Interrupt 09h.
  40. HOOK13          equ     13h                     ;Hooked Interrupt 13h.
  41. HOOK16        equ    16h            ;Hooked Interrupt 16h.
  42. HOOK28        equ    28h            ;Hooked Interrupt 28h.
  43. ;
  44. bellgate    db    0    ;Gate closed (=1) when in Bell routine.
  45.                 ;Gate open (=0) when not in Bell routine.
  46.  
  47. PICPORT        EQU    20h        ;I/O Port for the 8259A PIC chip.
  48. ISRREQ        EQU    00001011B    ;This is a byte defining the
  49.                     ;Operation Control Word 3 (OCW3) to
  50.                     ;output on port 20h to make the PIC
  51.                     ;chip's In Service Register available 
  52.                     ;for reading by the CPU on the
  53.                     ;next IN 20h command.
  54.  
  55. RSHIFT        equ    00000001B        ;Right Shift Key Flag weight.
  56. LSHIFT        equ    00000010B        ;Left Shift  Key Flag weight.
  57. CTRL        equ    00000100B        ;Ctrl        Key Flag weight.
  58. ALT        equ    00001000B        ;Alt         Key Flag weight.
  59. ;SCROLL         equ     00010000B               ;Scroll Lock Key Flag weight.
  60. ;NUM            equ     00100000B               ;Num Lock    Key Flag weight.
  61. ;CAPS           equ     01000000B               ;Caps Lock   Key Flag weight.
  62. INSRT        equ    10000000B        ;Ins         Key Flag weight.
  63. ;
  64. LockKeyMask     equ     10001111B               ;For masking out Scroll, Caps,
  65.                                                 ;and Num Lock bits in KeyFlags.
  66. indosptr    dd    ?
  67. criterrptr    dd    ?
  68. prtscrn         dd      00500000h
  69. hotkeyflag      db      0       ;hotkeyflag initially zero.
  70. diskflag        db      0       ;diskflag initially zero.
  71.  
  72. KEYFLAGBYTE     equ     CTRL+ALT                ;HotKey Flags
  73. HOTKEY          equ     21h                     ;'F' (for [F]astCD) key
  74.  
  75. TSRsigA         equ     '■F'            ;'FastCD' Signature
  76. TSRsigB         equ     'as'
  77. TSRsigC         equ     'tC'
  78. TSRsigD         equ     'D■'
  79.  
  80. Drive        db    ?
  81. Key        dw    ?
  82. data        dd    ?
  83. Tracks        dd    30 dup (?)
  84. DEC8        dd    ?
  85.  
  86. old_bar        db    104 dup (?)
  87.  
  88. IOCTL        db    13 dup (0)    ;ReqHdr
  89.         db    0        ;media descriptor byte
  90.         dd    ?        ;transfer address
  91.         dw    ?        ;bytes to transfer
  92.         dw    0        ;starting sector
  93.         dd    0        ;pointer to req. volume
  94.  
  95. DiskInfo    db    10        ;control block code
  96.         db    ?        ;lowest track
  97.         db    ?        ;highest track
  98.         dd    ?        ;starting point of lead-out track
  99.  
  100. TrakInfo    db    11        ;control block code
  101.         db    ?        ;Track number
  102.         dd    ?        ;starting point of track
  103.         db    ?        ;Track control info
  104.  
  105. LocHead        db    1        ;control block code
  106.         db    0        ;addressing mode
  107.         dd    ?        ;location of drivehead
  108.  
  109. Play        db    13 dup (0)    ;request header
  110.         db    1        ;addressing mode
  111.         dd    ?        ;starting sector
  112.         dd    ?        ;number of sector to play
  113.  
  114. Stop        db    13 dup(0)    ;request header
  115.  
  116. QInfo        db    12        ;control block code
  117.         db    ?        ;Control and ADR byte
  118.         db    ?        ;Track #
  119.         db    ?        ;point/index
  120.         db    ?        ;Track min
  121.         db    ?        ;Track sec
  122.         db    ?        ;Track frame
  123.         db    ?        ;Track zero
  124.         db    ?        ;disk min
  125.         db    ?        ;disk sec
  126.         db    ?        ;disk frame
  127.  
  128. AudInfo        db    3        ;control block code
  129.         db    ?        ;input channel for output channel 0
  130.         db    ?        ;volume for output channel 0
  131.         db    ?        ;input channel for output channel 1
  132.         db    ?        ;volume for output channel 1
  133.         db    ?        ;input channel for output channel 2
  134.         db    ?        ;volume for output channel 2
  135.         db    ?        ;input channel for output channel 3
  136.         db    ?        ;volume for output channel 3
  137.  
  138. BAR LABEL BYTE
  139.         DB      '█',3,'▓',115,'▒',115,'░'
  140.         DB      115,' ',121,'F',117,'a',117,'s',117,'t',117,'C',117,'D'
  141.         DB      117,' ',117,'▌',127,' ',127,'T',113,'r',113,'a',113,'c'
  142.         DB      113,'k',113,':',113,' ',113,' ',113,' ',113,' ',113,'·'
  143.         DB      113,' ',113,' ',113,' ',113,':',113,' ',113,' ',113,':'
  144.         DB      113,' ',113,' ',113,' ',127,'▌',127,' ',127,'V',117,'o'
  145.         DB      117,'l',117,':',117,' ',117,' ',117,' ',117,'∙',112,' '
  146.         DB      117,' ',117,' ',117,'░',115,'▒',115,'▓',115,'█',115
  147.  
  148. Entry    ENDP        ;v0.01
  149. ;
  150. ROUTINE         PROC    FAR
  151.  
  152. ;    Code for your HotKey-triggered TSR routine  GOES HERE:
  153.  
  154.         assume cs:codesg,ds:codesg
  155.  
  156. go:    
  157.     xor    bx,bx
  158.     mov    ax,1500h
  159.     int    2Fh            ;Get Nr of CD-ROM drives
  160.     mov    Drive,cl        ;CL contains 1st drive letter
  161.  
  162.     call    getbar
  163.     lea    si,bar
  164.     call    putbar
  165.  
  166.     call    GetAudInfo
  167.     mov    dl,AudInfo[2]
  168.     shr    dl,2
  169.     mov    si,112
  170.     call    dec8out
  171.     mov    dl,AudInfo[4]
  172.     shr    dl,2
  173.     mov    si,118
  174.     call    dec8out
  175.  
  176.     call    GetDiskInfo        ;Get # of tracks
  177.     call    GetDiskInfo        ;Twice if first time failed...
  178.  
  179.     xor    ch,ch
  180.     mov    cl,DiskInfo[2]        ;Last track
  181.     cmp    cl,0            ;No tracks...exit
  182.     jne    Trks
  183.     jmp    exit
  184.  
  185. Trks:    call    GetTrackInfo
  186.     les    ax,dword ptr TrakInfo[2]
  187.     mov    di,cx
  188.     shl    di,2
  189.     mov    word ptr Tracks[di+2],es
  190.     mov    word ptr Tracks[di],ax
  191.     loop    Trks
  192.  
  193.     call    GetAudInfo
  194.  
  195. no_key:
  196.     call    QChannelInfo
  197.     mov    al,QInfo[2]        ;contains track nr. as it appears on CD
  198.                     ;AL needs conversion:
  199.     mov    dl,al
  200.     and    dl,000001111b        ;save low nibble
  201.     and    al,011110000b        ;save high nibble
  202.     shr    al,4
  203.     mov    bl,0Ah
  204.     mul    bl            ;multiply high nibble by 10
  205.     add    dl,al
  206.     xor    dh,dh
  207.     mov    di,dx
  208.     mov    si,70
  209.     call    dec8out
  210.     mov    dl,QInfo[4]
  211.     mov    si,80
  212.     call    dec8out
  213.     mov    dl,QInfo[5]
  214.     mov    si,86
  215.     call    dec8out
  216.     mov    dl,QInfo[6]
  217.     mov    si,92
  218.     call    dec8out
  219.  
  220.     mov    ah,01h
  221.     int    16h
  222.     jz    no_key            ;keypressed?
  223.     xor    ah,ah
  224.     int    16h
  225.     mov    key,ax            ;read scancode and char
  226.     
  227.     cmp    ah,19h            ; P or p    (play)
  228.     jne    Key_S
  229.     mov    di,1
  230.     call    StopCD
  231.     call    PlayCD
  232.     jmp    no_key
  233.  
  234. Key_S:    cmp    ah,1Fh            ;S or s     (stop)
  235.     jne    KeyPgUp
  236.     call    StopCD
  237.     jmp    no_key
  238.  
  239. KeyPgUp:cmp    ax,4900h        ;PgUp       (skip to next track)
  240.     jne    KeyPgDn
  241.     xor    cx,cx
  242.     mov    cl,byte ptr DiskInfo[2]
  243.     cmp    cx,di
  244.     jne    nomax
  245.     mov    di,0
  246.  nomax:    inc    di
  247.     call    StopCD
  248.     call    PlayCD
  249.     jmp    no_key
  250.  
  251. KeyPgDn:cmp    ax,5100h        ;PgDn       (skip to prev. track)
  252.     jne    Key_Up
  253.     cmp    di,1
  254.     jne    nomin
  255.     mov    cx,0001
  256.     add    cl,byte ptr DiskInfo[2]
  257.     mov    di,cx
  258.  nomin:    dec    di
  259.     call    StopCD
  260.     call    PlayCD
  261.     jmp    no_key
  262.  
  263. Key_Up: cmp    ax,4800h
  264.     jne    Key_Dn
  265.     add    AudInfo[2],4
  266.     add    AudInfo[4],4
  267.     call    PutAudInfo
  268.     mov    dl,AudInfo[2]
  269.     shr    dl,2
  270.     mov    si,112
  271.     call    dec8out
  272.     mov    dl,AudInfo[4]
  273.     shr    dl,2
  274.     mov    si,118
  275.     call    dec8out
  276.     jmp    no_key
  277.  
  278. Key_Dn: cmp    ax,5000h
  279.     jne    Key_Lf
  280.     sub    AudInfo[2],4
  281.     sub    AudInfo[4],4
  282.     call    PutAudInfo
  283.     mov    dl,AudInfo[2]
  284.     shr    dl,2
  285.     mov    si,112
  286.     call    dec8out
  287.     mov    dl,AudInfo[4]
  288.     shr    dl,2
  289.     mov    si,118
  290.     call    dec8out
  291.     jmp    no_key
  292.  
  293. Key_Lf: cmp    ax,4B00h
  294.     jne    Key_Rg
  295.     sub    AudInfo[4],4
  296.     call    PutAudInfo
  297.     mov    dl,AudInfo[4]
  298.     shr    dl,2
  299.     mov    si,118
  300.     call    dec8out
  301.     jmp    no_key
  302.  
  303. Key_Rg: cmp    ax,4D00h
  304.     jne    Key_ESC
  305.     sub    AudInfo[2],4
  306.     call    PutAudInfo
  307.     mov    dl,AudInfo[2]
  308.     shr    dl,2
  309.     mov    si,112
  310.     call    dec8out
  311.     jmp    no_key
  312.  
  313. Key_ESC:cmp    ax,011Bh        ;ESC (exit program)
  314.     je    xit
  315.     jmp    no_key
  316. xit:    jmp    exit
  317.  
  318. ToCD    proc
  319.     push    ax
  320.     push    bx
  321.     push    cx
  322.     mov    ax,1510h
  323.     xor    ch,ch
  324.     mov    cl,Drive
  325.     les    bx,data
  326.     int    2Fh
  327.     pop    cx
  328.     pop    bx
  329.     pop    ax
  330.     ret
  331. endp    ToCD
  332.  
  333. GetDiskInfo    proc
  334.     mov    IOCTL[2],3        ;Command code
  335.  
  336.     mov    ax,cs
  337.     mov    word ptr IOCTL[16],ax    ;transfer address
  338.     mov    ax,offset DiskInfo
  339.     mov    word ptr IOCTL[14],ax    ;transfer address
  340.  
  341.     mov    IOCTL[18],7        ;bytes to transfer
  342.  
  343.     mov    ax,cs
  344.     mov    word ptr data[2],ax    ;address of IOCTL record
  345.     mov    ax,offset IOCTL
  346.     mov    word ptr data,ax    ;address of IOCTL record
  347.  
  348.     call    ToCD            ; Diskinfo[1,2] contains 1st & last trk
  349.  
  350.     xor    bx,bx
  351.     mov    bl, byte ptr DiskInfo[2]
  352.     mov    di,bx
  353.     inc    di
  354.     shl    di,2
  355.     les    ax,dword ptr DiskInfo[3]
  356.     mov    word ptr Tracks[di+2],es    ;end of disc
  357.     mov    word ptr Tracks[di],ax
  358.     ret
  359.  
  360. endp    GetDiskInfo
  361.  
  362. GetTrackInfo    proc
  363.     mov    IOCTL[2],3        ;command code
  364.     
  365.     mov    ax,cs
  366.     mov    word ptr IOCTL[16],ax    ;transfer address
  367.     mov    ax,offset TrakInfo
  368.     mov    word ptr IOCTL[14],ax    ;transfer address
  369.  
  370.     mov    IOCTL[18],7
  371.  
  372.     mov    TrakInfo[1],cl        ;contains track number
  373.  
  374.     mov    ax,cs
  375.     mov    word ptr data[2],ax    ;address of IOCTL record
  376.     mov    ax,offset IOCTL
  377.     mov    word ptr data,ax
  378.  
  379.     call    ToCD
  380.     ret
  381. endp    GetTrackInfo
  382.  
  383. PutAudInfo    proc            ;DL=left, DH=right volume
  384.     mov    IOCTL[2],12        ;command code
  385.     
  386.     mov    ax,cs
  387.     mov    word ptr IOCTL[16],ax    ;transfer address
  388.     mov    ax,offset AudInfo
  389.     mov    word ptr IOCTL[14],ax    ;transfer address
  390.  
  391.     mov    IOCTL[18],9
  392.  
  393.     mov    ax,cs
  394.     mov    word ptr data[2],ax    ;address of IOCTL record
  395.     mov    ax,offset IOCTL
  396.     mov    word ptr data,ax
  397.  
  398.     call    ToCD
  399.     ret
  400. endp    PutAudInfo
  401.  
  402. GetAudInfo    proc
  403.     mov    IOCTL[2],3        ;command code
  404.     inc    AudInfo[0]
  405.     
  406.     mov    ax,cs
  407.     mov    word ptr IOCTL[16],ax    ;transfer address
  408.     mov    ax,offset AudInfo
  409.     mov    word ptr IOCTL[14],ax    ;transfer address
  410.  
  411.     mov    IOCTL[18],9
  412.  
  413.     mov    ax,cs
  414.     mov    word ptr data[2],ax    ;address of IOCTL record
  415.     mov    ax,offset IOCTL
  416.     mov    word ptr data,ax
  417.  
  418.     call    ToCD
  419.     dec    AudInfo[0]
  420.     ret
  421. endp    GetAudInfo
  422.  
  423.  
  424. PlayCD    proc                ;DI must contain track number
  425.     push    di
  426.     mov    Play[2],132        ;command code
  427.  
  428.     shl    di,2
  429.  
  430.     les    bx,dword ptr Tracks[di]
  431.     mov    word ptr Play[16],es
  432.     mov    word ptr Play[14],bx
  433.     mov    cx,es
  434.  
  435.     call    RedBook2HSG
  436.     mov    bx,ax
  437.     mov    cx,dx
  438.     push    bx
  439.     push    cx
  440.     
  441.     mov    al,DiskInfo[2]        ;begin of last track
  442.     inc    al
  443.     xor    ah,ah
  444.     shl    ax,2            ;it are dwords
  445.     mov    di,ax
  446.  
  447.     call    RedBook2HSG
  448.  
  449.     pop    cx
  450.     pop    bx
  451.  
  452.     sub    ax,bx
  453.     jnc    @1
  454.     dec    dx
  455. @1:    sub    dx,cx
  456.     
  457.     mov    word ptr Play[20],dx
  458.     mov    word ptr Play[18],ax
  459.  
  460.     mov    ax,cs
  461.     mov    word ptr data[2],ax    ;address of Play record
  462.     mov    ax,offset Play
  463.     mov    word ptr data,ax
  464.  
  465.     call    ToCD
  466.  
  467.     pop    di
  468.     ret
  469. endp PlayCD
  470.  
  471. QChannelInfo    proc
  472.     mov    IOCTL[2],3        ;command code
  473.     
  474.     mov    ax,cs
  475.     mov    word ptr IOCTL[16],ax    ;transfer address
  476.     mov    ax,offset QInfo
  477.     mov    word ptr IOCTL[14],ax    ;transfer address
  478.  
  479.     mov    IOCTL[18],11
  480.  
  481.     mov    ax,cs
  482.     mov    word ptr data[2],ax    ;address of IOCTL record
  483.     mov    ax,offset IOCTL
  484.     mov    word ptr data,ax
  485.  
  486.     call    ToCD
  487.     ret
  488. endp    QChannelInfo
  489.  
  490.  
  491. StopCD proc
  492.     mov    Stop[2],133        ;command code
  493.     
  494.     mov    ax,cs
  495.     mov    word ptr data[2],ax    ;address of Stop record
  496.     mov    ax,offset Stop
  497.     mov    word ptr data,ax
  498.  
  499.     call    ToCD
  500.  
  501.     ret
  502. endp StopCD
  503.  
  504.  
  505. RedBook2HSG proc
  506.  
  507.     mov    ax,word ptr Tracks[di+2]    ;get high word
  508.     mov    cx,4500
  509.     mul    cx
  510.  
  511.     push    ax            ;put ax aside
  512.  
  513.     mov    al,byte ptr Tracks[di+1]
  514.     mov    cl,75
  515.     mul    cl
  516.     mov    bx,ax
  517.  
  518.     pop    ax            ;get ax back
  519.  
  520.     add    ax,bx
  521.     jnc    @2            ;carry? then decrease high word
  522.     inc    dx
  523. @2:    mov    cl,byte ptr Tracks[di]
  524.     xor    ch,ch
  525.     add    ax,cx
  526.     jnc    @3
  527.     inc    dx
  528. @3:    sub    ax,150
  529.     jnc    @4
  530.     dec    dx
  531. @4:    
  532.     ret
  533. endp RedBook2HSG
  534.  
  535. dec8out    proc
  536.  
  537.     push    di
  538.     push    ds
  539.     mov    bx,0B800h
  540.     mov    ds,bx
  541.     xor    cx,cx            ; initialize a counter
  542.     mov    di,1            ; point to a buffer
  543.     mov    byte ptr cs:DEC8[1],'0'    ; zero unused var's
  544.     mov    byte ptr cs:DEC8[2],'0'    ;  "     "      "
  545.     mov    byte ptr cs:DEC8[3],'0'    ;  "     "      "
  546.  
  547. dec8out1:
  548.     push    cx        ; save the count
  549.     mov    al,dl        ; AX has the numerator
  550.     xor    ah,ah        ; clear upper half
  551.     mov    cl,10        ; divisor of 10
  552.     div    cl        ; divide
  553.     mov    dl,al        ; get quotient
  554.     mov    al,ah        ; get remainder
  555.     add    al,30h        ; increase to ASCII
  556.     mov    byte ptr cs:DEC8[di],al; put in tbuff
  557.     inc    di        ; point to next byte
  558.  
  559.     pop    cx        ; restore count
  560.     inc    cx        ; count the digit
  561.     cmp    dl,0        ; done ?
  562.     jnz    dec8out1
  563.  
  564.     mov    al,byte ptr cs:DEC8[2]
  565.     mov    ds:[si],al
  566.     mov    al,byte ptr cs:DEC8[1]
  567.     mov    ds:[si+2],al
  568.  
  569.     pop    ds
  570.     pop    di
  571.  
  572.     ret            ; return
  573. dec8out    endp
  574.  
  575.  
  576. putbar    proc
  577.     push    di
  578.     push    ds
  579.     cld
  580.     mov    dx,cs
  581.     mov    ds,dx
  582.     mov    dx,0B800h
  583.     mov    es,dx
  584.  
  585.     mov    di,28
  586.     mov    cx,104
  587.     rep    movsb
  588.  
  589.     pop    ds
  590.     pop    di
  591.     
  592.     ret
  593. putbar    endp
  594.  
  595. getbar    proc
  596.     push    di
  597.     push    ds
  598.  
  599.     cld
  600.     mov    dx,cs
  601.     mov    es,dx
  602.     mov    dx,0B800h
  603.     mov    ds,dx
  604.     mov    si,28
  605.     lea    di,old_bar
  606.     mov    cx,104
  607.     rep    movsb
  608.  
  609.     pop    ds
  610.     pop    di
  611.  
  612.     ret
  613. getbar    endp
  614.  
  615. exit:    lea    si,old_bar
  616.     call    putbar
  617.  
  618.     ret                     ;Return from TSR routine.
  619. ;
  620. ROUTINE         endp
  621. ;
  622. ;    End of your HotKeyed TSR routine.
  623.  
  624. NewInt09    PROC    FAR        ;v0.01
  625. ;
  626.         pushf            ;Push flags as a true interrupt would.
  627.                 cli                     ;Be sure interrupts are disabled.
  628.         call    CS:oldint09    ;Call FAR PTR address of old interrupt
  629. ;                    ;     handler routine.
  630.                 push    ax      ;Prepare to check for Hotkey.
  631.                 push    bx      ;Save all registers (DS is already pushed).
  632.                 push    cx
  633.                 push    dx
  634.                 push    si
  635.                 push    di
  636.                 push    bp
  637.                 push    ds
  638.                 push    es
  639. ;
  640.                 push    CS              ;Set up data segment
  641.                 pop     DS              ;register to point to code segment.
  642. ;
  643.                 ASSUME  DS:codesg      ;v0.01
  644. ;
  645.                 in      al,60h          ;Get current Key Scan Code.
  646.                 cmp     al,HOTKEY       ;Is it HotKey's Scan Code?
  647.                 jne     Exit09          ;Exit if not.
  648.                 mov     ah,02h          ;Int16h,Fcn02h:GetKEYFLAGBYTE.
  649.                 Int     16h             ;Return Key Flag Byte in al.
  650.                 and     al,LockKeyMask  ;Mask out Num, Caps, Scroll Lock bits.
  651.                 cmp     al,KEYFLAGBYTE  ;Are the HotKey Flags active ?
  652.                 jne     Exit09          ;Exit if not.
  653. ;
  654. ClrKbdBuf:      ;Clear Keyboard buffer:
  655.                 mov     ah,01h          ;Get Keyboard buffer status
  656.                 int     16h             ;via BIOS Interrupt 16h.
  657.                 jz      BufClr          ;Jump if buffer empty.
  658.                 mov     ah,00h          ;Get key from buffer (to purge it)
  659.                 int     16h             ;via BIOS Interrupt 16h.
  660.                 jmp     ClrKbdBuf       ;Loop back to purge another key.
  661. BufClr:
  662. ;
  663.                 cmp     bellgate,0      ;Is it clear to re-enter Hotkey code?
  664.                 jne     BusyExit09      ;Exit if not,
  665.                 mov     bellgate,1      ;Else, close gate and proceed.
  666. ;
  667.                 CLI                     ;DISABLE INTERRUPTS
  668.  
  669. HotKeyPressed:
  670.                 mov     al,ISRREQ       ;al=PIC's OCW3 to ask for ISR Register.
  671.         out    PICPORT,al    ;Tell PIC to get ISR ready for reading.
  672.         jmp    Dally        ;Give PIC time to make ISR available.
  673. Dally:        in    al,PICPORT    ;Fetch the ISR Register from PIC.
  674.                 or      al,al           ;Activate processor flags.
  675.                 jnz     setflg         ;If al not zero, go set flag.
  676. ;
  677. HotKeyNoHWI:
  678.         les    bx,indosptr    ;es:bx = pointer to InDOS flag
  679.         mov    al,es:[bx]    ;al = InDOS flag.
  680.                 or      al,al           ;Activate processor flags.
  681.                 jnz     setflg         ;Jump if InDOS not zero.
  682.  
  683.                 les     bx,criterrptr   ;es:bx = pointer to CritErr flag.
  684.                 mov     al,es:[bx]      ;al = CritErr flag.
  685.  
  686.                 or      al,diskflag     ;al = CritErr | diskflag
  687.                                         ; (| => Logical OR).
  688.                 jnz     Exit09          ;If al not zero, try again later.
  689.  
  690.                 les     bx,prtscrn      ;ES:bx = pointer to PrtScrn busy flag.
  691.                 cmp     BYTE PTR es:[bx],1      ;Is PrtScrn in progress?
  692.                 je      Exit09          ;If so, try again later.
  693. ;
  694.                 STI                     ;Allow other interrupts in our TSR.
  695. ;
  696.                 call    ROUTINE         ;All is clear!, so call routine.
  697.                 mov     hotkeyflag,0    ;Be sure HotKey flag is reset.
  698.                 jmp     SHORT Exit09    ;Exit after TSR routine.
  699. ;
  700. setflg:
  701.                 mov     hotkeyflag,1    ;Set HotKey Flag for use by Int28h.
  702. ;
  703. Exit09:
  704.                 mov     CS:bellgate,0   ;Open gate allowing new HotKey detect.
  705. BusyExit09:
  706.                 pop     es              ;Restore all registers
  707.                 pop     ds
  708.                 ASSUME  DS:NOTHING      ;v0.01
  709.                 pop     bp
  710.         pop    di
  711.         pop    si
  712.         pop    dx
  713.         pop    cx
  714.         pop    bx
  715.         pop    ax
  716. ;
  717.         iret
  718. ;
  719. NewInt09    ENDP            ;v0.01
  720. ;
  721. NewInt13        PROC    FAR             ;We hook Int13h only for purpose
  722.                                         ;of setting a flag to prevent our
  723.                                         ;TSR from triggering during time-
  724.                                         ;critical Disk accesses.
  725.                 mov     CS:diskflag,1   ;Set flag to show Disk access.
  726. ;
  727.                 pushf                   ;Invoke prior Int13 handler
  728.                 cli                     ;(be sure interrupts disabled)
  729.                 call    CS:oldint13     ;by simulating an interrupt.
  730. ;
  731.                 mov     CS:diskflag,0   ;Clear flag to show Disk finished.
  732. ;
  733.                 RET     2               ;Return from interrupt while
  734.                                         ;preserving flags.
  735. ;
  736. NewInt13        ENDP
  737.  
  738. NewInt16    PROC    FAR        ;v0.01
  739. ;
  740.                 push    ds              ;Entry for New Int. Handler.
  741. ;                                       ;Save required registers.
  742. ;
  743.                 push    CS              ;Set data seg   v0.01
  744.                 pop     DS              ;to our codesg v0.01
  745.         ASSUME    DS:codesg    ;v0.01
  746. ;
  747.         cmp    ax,TSRsigA    ;Is ax = TSR signature word A?
  748.         jne    Exit16        ;No, let regular Int16 handle this.
  749.         cmp    bx,TSRsigB    ;Is bx = TSR signature word B?
  750.         jne    Exit16        ;No, let regular Int16 handle this.
  751.         cmp    cx,TSRsigC    ;Is cx = TSR signature word C?
  752.         jne    Exit16        ;No, let regular Int16 handle this.
  753.         cmp    dx,TSRsigD    ;Is dx = TSR signature word D?
  754.         jne    Exit16        ;No, let regular Int16 handle this.
  755. ;
  756.                 xchg    bx,cx   ;Exchange regs. (DOS Int16h wouldn't do this)
  757.         xchg    ax,dx    ;   "         "        "
  758. ;
  759.                 pop     ds      ;Restore regs.
  760.                 iret            ;Return from Int to TSR Initialize routine.
  761. ;
  762. Exit16:
  763.                 pop     ds                      ;Restore all registers
  764.         ASSUME    DS:NOTHING    ;v0.01
  765. ;
  766.                 jmp     CS:oldint16
  767. ;
  768. NewInt16        ENDP            ;v0.01
  769.  
  770. NewInt28    PROC    FAR        ;v0.01
  771. ;
  772.                 pushf                   ;Call prior handler.
  773.                 cli
  774.                 call    CS:oldint28
  775. ;
  776.                 cmp     CS:hotkeyflag,1 ;Has HotKey been pressed?
  777.                 jne     QuickExit       ;Exit if not.
  778. ;
  779.                 cmp     CS:bellgate,1   ;Is gate closed?
  780.                 je      QuickExit       ;If so, exit.
  781.                 mov     CS:bellgate,1   ;Else close gate and proceed.
  782. ;
  783.                 CLI                     ;DISABLE INTERRUPTS
  784.  
  785.                 push    ax              ;Entry for New Int. Handler.
  786.                 push    bx              ;Save all registers.
  787.                 push    cx
  788.                 push    dx
  789.                 push    si
  790.                 push    di
  791.                 push    bp
  792.                 push    ds
  793.                 push    es
  794. ;
  795.                 push    CS
  796.                 pop     DS
  797.                 ASSUME  DS:codesg      ;v0.01
  798. ;
  799.                 les     bx,indosptr             ;ES:bx points to InDOS flag.
  800.                 cmp     BYTE PTR ES:[bx],1      ;Is InDOS flag above 1?
  801.                 ja      Exit28                  ;Exit if InDOS > 1.
  802. ;
  803. HotKeyPressed2:
  804.                 mov     al,ISRREQ       ;al=PIC's OCW3 to ask for ISR Register.
  805.         out    PICPORT,al    ;Tell PIC to get ISR ready for reading.
  806.         jmp    Dally2        ;Give PIC time to make ISR available.
  807. Dally2:        in    al,PICPORT    ;Fetch the ISR Register from PIC.
  808. ;
  809.                 or      al,diskflag     ;al = ISR | diskflag. (| => Logical OR).
  810.                 jnz     Exit28          ;If al not zero, try again later.
  811. ;
  812.                 les     bx,prtscrn      ;ES:bx = pointer to PrtScrn busy flag.
  813.                 cmp     BYTE PTR es:[bx],1      ;Is PrtScrn in progress?
  814.                 je      Exit28                  ;If so, Exit w/o triggering TSR.
  815. ;
  816.                 STI                     ;ENABLE OTHER INTERRUPTS.
  817. ;
  818. HotKeyFlagSet:
  819. ;
  820.                 call    ROUTINE         ;Call TSR routine; DOSOK & No Hardware
  821.                     ;interrupts being serviced.
  822.                 mov     CS:hotkeyflag,0    ;Clear HotKey Flag.
  823. ;
  824. Exit28:
  825.                 pop     es                      ;Restore all registers
  826.                 pop     ds
  827.                 ASSUME  ds:NOTHING
  828.                 pop     bp
  829.         pop    di
  830.         pop    si
  831.         pop    dx
  832.         pop    cx
  833.         pop    bx
  834.         pop    ax
  835.                 mov     CS:bellgate,0
  836. ;
  837. QuickExit:
  838.                 iret
  839. ;
  840. NewInt28        ENDP            ;v0.01
  841. ;    -END OF TSR's RESIDENT CODE-
  842.  
  843. ;       BEGINNING OF TSR's INITIALIZATION CODE (THE "BOOSTER"):
  844. ;
  845. TSRinit        PROC    NEAR                ;v0.01
  846. EndDump        EQU    $    
  847.  
  848.         xor    bx,bx
  849.         mov    ax,1500h
  850.         int    2Fh            ;Get Nr of CD-ROM drives
  851.         cmp    bx,0            ;Nr of CD-ROM drives
  852.         jz    NoMSCD            ;0 -> driver not installed
  853.         jmp    DosCHK
  854. NoMSCD:        mov    dx,OFFSET NoMSCDEX
  855.         mov    ah,09h
  856.         int    21h
  857.         mov    ax,4C00h
  858.         int    21h
  859. ;
  860. DosCHK:         mov     ah,30h                  ;Fcn 30h = Get DOS Version
  861.                 int     21h                     ;DOS Version = al.ah
  862. ;
  863.                 cmp     al,1         ;Is this DOS Version 1.x?
  864.                 ja      DOSverOK     ;If not, DOS version is OK.
  865.                 push    bx           ;A "push" for the "pop" at DOSver1 label.
  866.                 jmp     DOSver1      ;If so, TSR won't work so exit.
  867. ;
  868. DOSverOK:
  869.                 mov     ax,TSRsigA              ;Prime registers for our
  870.                 mov     bx,TSRsigB              ;Int16h handler's check
  871.                 mov     cx,TSRsigC              ;for prior installation
  872.                 mov     dx,TSRsigD              ;thru TSR signature words.
  873. ;
  874.                 Int     16h                     ;Check prior installation.
  875. ;
  876.                 cmp     ax,TSRsigD              ;Was TSR signature detected?
  877.                 jne     Install                 ;If not, Install it.
  878.                 cmp     bx,TSRsigC
  879.                 jne     Install         
  880.                 cmp     cx,TSRsigB
  881.                 jne     Install         
  882.                 cmp     dx,TSRsigA
  883.                 jne     Install
  884.  
  885.                 mov     dx,Offset PriorInstMsg  ;DX points to message.
  886.                 mov     ah,09h                  ;DOS Fcn. 09h=Display String.
  887.                 Int     21h                     ;Display String via DOS.
  888. ;
  889.                 mov     ax,4C00h                ;Fcn 4C = DOS Terminate call
  890.                 Int     21h                     ;Do it.
  891. ;
  892. Install:
  893. ;
  894.                 ;Get segment of Environment
  895.         ;from 02Ch in the Program
  896.         ;Segment Prefix (PSP).
  897. ;
  898.                 mov     ES,envseg       ;ES=PSP's environ seg   v0.01
  899.                 mov     ah,49h          ;DOS Fcn 49h = Release Memory
  900.                 int     21h             ;Release it via DOS interrupt.
  901. ;
  902. ; Allocate the memory needed by the tiny 'Pseudo-Environment":
  903.  
  904.                 mov     bx,1            ;Allocate one parag. (16bytes)
  905.                 mov     ah,48h          ;and return allocation
  906.                 int     21h             ;segment in ax via DOS call.
  907. ;
  908.                 mov     ES,ax           ;Pseudo-Env. Segment to ES.
  909.         mov    si,OFFSET PseudoEnv    ;si=source string OFFSET.
  910.                 mov     di,0            ;di=destination string OFFSET.
  911.                 mov     cx,ENVLNGTH     ;cx=Bytes in Pseudo-Env.string.
  912.                 cld                     ;Forward string move direction.
  913.         rep    movsb    ;Move Pseudo-Env. string @ DS:si to ES:di
  914. ;
  915.         mov    envseg,ES    
  916. ;
  917.                 mov     ax,3500H+HOOK09 ;Get old Int 9 vector   v0.01
  918.                 int     21h             ;Int.Vector in ES:BX via DOS.
  919.         mov    Word Ptr oldint09,bx    ;Save Offset of Old Interrupt.
  920.         mov    word ptr oldint09+2,ES    ;save seg        v0.01
  921.                 mov     ax,2500H+HOOK09         ;Set new Int 9 vector   v0.01
  922.         mov    dx,Offset NewInt09    ;dx=Offset of New Int Handler.
  923.                 int     21h                     ;Set New Int via DOS.
  924.  
  925.                 mov     ax,3500H+HOOK13         ;Get old Int 13 vector
  926.                 int     21h                     ;Int.Vector in ES:BX via DOS.
  927.                 mov     Word Ptr oldint13,bx    ;Save Offset of Old Interrupt.
  928.                 mov     word ptr oldint13+2,ES  ;save Segment.
  929.                 mov     ax,2500H+HOOK13         ;Set new Int 13 vector.
  930.                 mov     dx,Offset NewInt13      ;dx=Offset of New Int Handler.
  931.                 int     21h                     ;Set New Int via DOS.
  932.  
  933.                 mov     ax,3500H+HOOK16         ;get old Int 16H vector v0.01
  934.                 int     21h                     ;Int.Vector in ES:BX via DOS.
  935.                 mov     Word Ptr oldint16,bx    ;Save Offset of Old Interrupt.
  936.                 mov     word ptr oldint16+2,ES  ;save segment           v0.01
  937.                 mov     ax,2500H+HOOK16         ;set new Int 16H vector v0.01
  938.                 mov     dx,Offset NewInt16      ;dx=Offset of New Int Handler.
  939.                 int     21h                     ;Set New Int via DOS.
  940.  
  941.                 mov     ax,3500H+HOOK28         ;Get old Int 28H vector v0.01
  942.                 int     21h                     ;Int.Vector in ES:BX via DOS.
  943.                 mov     Word Ptr oldint28,bx    ;Save Offset of Old Interrupt.
  944.                 mov     word ptr oldint28+2,ES  ;save segment           v0.01
  945.                 mov     ax,2500H+HOOK28         ;set new Int 28H vector v0.01
  946.                 mov     dx,Offset NewInt28      ;dx=Offset of New Int Handler.
  947.                 int     21h                     ;Set New Int via DOS.
  948.                 mov     ah,34h                  ;DOS FCN=34h:Get InDOS Pointer.
  949.                 int     21h                     ;Pointer in ES:BX
  950.                 mov     Word Ptr indosptr,bx    ;Save Offset of InDOS flag.
  951.                 mov     Word Ptr indosptr+2,ES  ;Save Segment of InDOS flag.
  952. ;
  953.                 mov     Word Ptr criterrptr+2,ES ;Also, Seg of CritErr flag.
  954.                 push    bx      ;Save indosptr on stack for use below.
  955.  
  956.                 mov     ah,30h          ;Fcn 30h = Get DOS Version
  957.                 int     21h             ;DOS Version = al.ah
  958.  
  959.                 cmp     al,2            ;Is it DOS Version 2.x?
  960.                 je      DOSver2         ;If yes, jump;
  961.                 ja      DOSver3         ;or, if later version, jump;
  962.                                         ;else, it's DOS Version 1.x:
  963. ;
  964. DOSver1:        ;If here, DOS Version 1.x is being run:
  965.                 mov     dx,OFFSET BailOutMsg    ;TBONES needs DOS 2.x or later.
  966.                 mov     ah,09h                  ;Say we're sorry, but NO GO
  967.                 int     21h                     ;via DOS.
  968.                 pop     bx                      ;Clear stack.
  969.                 int     20h                     ;Terminate without installing
  970.                                                 ;in only way DOS 1.x knows.
  971. ;
  972. DOSver2:        ;If here, DOS Version 2.x is being run:
  973.                 pop     bx                      ;Get indosptr from stack.
  974.                 inc     bx                      ;CritErr flag is @ indosptr+1.
  975.                 mov     Word Ptr criterrptr,bx  ;Save CritErr Pointer.
  976.                 jmp     Announce                ;Go announce TSR installed.
  977. ;
  978. DOSver3:        ;If here, DOS Version 3.+ is being run:
  979.                 pop     bx                      ;Get indosptr from stack.
  980.                 dec     bx                      ;CritErr flag is @ indosptr-1.
  981.                 mov     Word Ptr criterrptr,bx  ;Save CritErr Pointer.
  982. ;
  983. Announce:
  984.                 mov     dx,Offset InstallMsg    ;DX points to message.
  985.                 mov     ah,09h                  ;DOS Fcn. 09h=Display String.
  986.                 int     21h                     ;Display String via DOS.
  987. ;
  988.                 mov     dx,(EndDump-BeginDump+0Fh)/16
  989.                 mov     ah,31h                  ;DOS FCN 31h=TSR Call.
  990.                 int     21h                     ;Go Resident via DOS TSR call.
  991. ;
  992. PseudoEnv:      DB      ' ',0,0,1,0,'■FastCD■',0
  993. ENVLNGTH    EQU    $-PseudoEnv
  994. ;
  995.  
  996.  
  997. NoMSCDEX:
  998.                 db    'FastCD requires MSCDEX.EXE',0Dh,0Ah,'$'
  999.  
  1000.  
  1001. BailOutMsg:
  1002.                 db      0Dh,0Ah
  1003.                 db      'Sorry. FastCD requires DOS v2.0 or better'
  1004.                 db      0Dh,0Ah,'$'
  1005. PriorInstMsg:
  1006.                 db      0Dh,0Ah
  1007.                 db      'FastCD is already installed'
  1008. InstallMsg:
  1009.                 db      0Dh,0Ah
  1010.                 db      'Use Ctrl-Alt-F to activate program'
  1011.                 db      0Dh,0Ah
  1012.                 db      0Dh,0Ah
  1013.                 db      'FastCD v0.9ß ∙ A TSR Digital Audio CD Player'
  1014.                 db      0Dh,0Ah
  1015.                 db      'Copyright (C) 1995 by Johan Prins'
  1016.                 db      0Dh,0Ah,'$'
  1017. ;
  1018. TSRinit         ENDP    ;v0.01
  1019.  
  1020. codesg         ends
  1021.                 end     Entry
  1022.